package com.xs.ahoi.hcxs.dao;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import com.xs.ahoi.hcxs.model.Book;
import com.xs.ahoi.hcxs.utils.DateUtil;
import com.xs.ahoi.hcxs.utils.FileUtil;
import com.xs.ahoi.hcxs.utils.ToastUtil;
import org.apache.commons.collections4.CollectionUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * author: ahoi
 * date: 2018/6/21 13:28
 * description:
 */
public class BookDao {

    private static BookDao instance;
    private static SQLiteDatabase db;

    private BookDao() {
    }

    public static synchronized BookDao getInstance() {
        if (db == null) {
            db = DBHelper.getInstance().getDb();
        }
        if (instance == null) {
            instance = new BookDao();
        }
        return instance;
    }

    // 保存或更新一本书
    public void saveOrUpdate(String path) {
        File file = FileUtil.getFile(path);
        if (!file.exists()) {
            ToastUtil.show("日志文件不存在!");
            return;
        }
        Book book = getByPath(path);
        if (book != null) {
            book.setName(file.getName());
            book.setTotalLenth(file.length());
            updateInfo(book.getId(), book);
        } else {
            book = new Book();
            book.setPath(path);
            book.setName(file.getName());
            book.setTotalLenth(file.length());
            save(book);
        }
    }

    // 保存一本书
    public void save(Book book) {
        List<Book> books = new ArrayList<>();
        books.add(book);
        save(books);
    }

    // 批量保存
    public void save(List<Book> books) {
        // 开始事务
        db.beginTransaction();

        String sql = "insert into " + DBHelper.TABLE_NAME_BOOK +
                " (path, name, total_length, last_read_position) values (?, ?, ?, ?);";

        try {
            // 批量插入目录
            for (Book book : books) {
                db.execSQL(sql, new Object[]{book.getPath(), book.getName(), book.getTotalLenth(), -1});
            }

            // 设置事务处理成功，不设置会自动回滚不提交
            db.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 提交事务
            db.endTransaction();
        }
    }

    /**
     * 更新最后阅读时间和位置
     */
    public void updateLastRead(int bookId, int lastReadPosition) {
        String sql = "update " + DBHelper.TABLE_NAME_BOOK + " set last_read_time = ?, last_read_position = ? where id = ?;";
        db.execSQL(sql, new Object[]{DateUtil.getTime(), lastReadPosition, bookId});
    }

    /**
     * 更新置顶时间
     */
    public void updateSetTop(int bookId, long setTopTime) {
        String sql = "update " + DBHelper.TABLE_NAME_BOOK + " set set_top_time = ? where id = ?;";
        db.execSQL(sql, new Object[]{setTopTime, bookId});
    }

    /**
     * 更新书籍信息
     */
    public void updateInfo(int bookId, Book book) {
        String sql = "update " + DBHelper.TABLE_NAME_BOOK + " set name = ?, total_length = ? where id = ?;";
        db.execSQL(sql, new Object[]{book.getName(), book.getTotalLenth(), bookId});
    }

    /**
     * 更新书籍路径
     */
    public void updatePath(int bookId, Book book) {
        String sql = "update " + DBHelper.TABLE_NAME_BOOK + " set path = ?, name = ? where id = ?;";
        db.execSQL(sql, new Object[]{book.getPath(), book.getName(), bookId});
    }

    // 删除书籍
    public void delete(Book book) {
        List<Book> books = new ArrayList<>();
        books.add(book);
        deleteBatch(books);
    }

    // 批量删除书籍
    public void deleteBatch(List<Book> books) {
        if (CollectionUtils.isNotEmpty(books)) {
            String ids = "";
            for (Book book : books) {
                ids += book.getId() + ",";

                // 移除缓存中的小说的编码
                ConfigDao.getInstance().removeCharset(book.getPath());
            }
            ids = ids.substring(0, ids.length() - 1);
            String sql = "delete from " + DBHelper.TABLE_NAME_BOOK + " where id in (" + ids + ")";
            db.execSQL(sql);

            // 删除目录
            CatalogDao.getInstance().deleteByBookId(ids);

            // 删除书签
            BookMarkDao.getInstance().deleteByBookId(ids);
        }
    }

    /**
     * 根据目录删除
     */
    public void deleteByPath(List<String> paths) {
        if (CollectionUtils.isNotEmpty(paths)) {
            List<Book> books = paths.stream().map(this::getByPath).filter(Objects::nonNull).collect(Collectors.toList());
            deleteBatch(books);
        }
    }

    // 查询所有书
    public List<Book> listAll() {
        Cursor cursor = null;
        List<Book> list = new ArrayList<>();
        String sql = "select * from " + DBHelper.TABLE_NAME_BOOK + " order by set_top_time desc, last_read_time desc ";
        try {
            cursor = db.rawQuery(sql, null);
            while (cursor.moveToNext()) {
                list.add(cursorToBook(cursor));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return list;
    }

    /**
     * 根据点击的id获取一本书
     */
    public Book getById(int bookId) {
        Cursor cursor = null;
        Book book = null;
        String sql = "select * from " + DBHelper.TABLE_NAME_BOOK + " where id = ?";
        try {
            cursor = db.rawQuery(sql, new String[]{bookId + ""});
            while (cursor.moveToNext()) {
                book = cursorToBook(cursor);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return book;
    }

    /**
     * 根据路径获取一本书
     */
    public Book getByPath(String path) {
        Cursor cursor = null;
        Book book = null;
        String sql = "select * from " + DBHelper.TABLE_NAME_BOOK + " where path = ?";
        try {
            cursor = db.rawQuery(sql, new String[]{path});
            while (cursor.moveToNext()) {
                book = cursorToBook(cursor);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return book;
    }

    private Book cursorToBook(Cursor cursor) {
        Book book = new Book();
        book.setId(cursor.getInt(0));
        book.setPath(cursor.getString(1));
        book.setName(cursor.getString(2));
        book.setTotalLenth(cursor.getLong(3));
        book.setLastReadTime(cursor.getLong(4));
        book.setLastReadPosition(cursor.getInt(5));
        book.setSetTopTime(cursor.getLong(6));
        return book;
    }

}
